package com.supermarket.manage.provider.product.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.supermarket.manage.common.constant.ProductConstant;
import com.supermarket.manage.common.constant.RedisKeyConstant;
import com.supermarket.manage.common.dto.PageBean;
import com.supermarket.manage.common.dto.prod.request.ProdPageParams;
import com.supermarket.manage.common.dto.prod.response.ProductDto;
import com.supermarket.manage.common.pojo.Product;
import com.supermarket.manage.common.utils.BigDecimalUtil;
import com.supermarket.manage.provider.api.product.ProductCategoryService;
import com.supermarket.manage.provider.api.product.ProductService;
import com.supermarket.manage.provider.product.mapper.ProductMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author Faxon
 * @version 1.0
 * @date 2020-03-08 19:16
 **/
@Service(version = "1.0.0")
public class ProductServiceImpl implements ProductService {
    @Resource
    private ProductMapper productMapper;

    @Resource
    private ProductCategoryService productCategoryService;

    @Override
    public Integer getCountByPname(Product product) {
        QueryWrapper<Product> wrapper = new QueryWrapper<>();
        wrapper.eq("pname", product.getPname()).eq("buyer_id", product.getBuyerId());
        return productMapper.selectCount(wrapper);
    }

    @Override
    public Boolean addProduct(Product product) {
        Date date = new Date();
        product.setStockNumber(BigDecimalUtil.getNumber(new BigDecimal("0"), 2));
        product.setStatus(ProductConstant.SHELVES_PROD);
        product.setCreated(date);
        product.setUpdated(date);
        return productMapper.insert(product) == 1;
    }

    @Override
    public Boolean deleteProdByPid(String pid) {
        Product product = new Product();
        product.setPid(pid);
        product.setStatus(ProductConstant.TAKEOFF_PROD);
        product.setUpdated(new Date());
        return productMapper.updateById(product) == 1;
    }

    @Override
    public Product getProdByPid(String pid) {
        return productMapper.selectById(pid);
    }

    @Override
    public Boolean updateProd(Product oldProd, Product product) {
        Product newProd = new Product();
        newProd.setPid(product.getPid());
        newProd.setUpdated(new Date());
        if (!oldProd.getPname().equals(product.getPname())) {
            newProd.setPname(product.getPname());
        }
        if (!oldProd.getCostPrice().equals(product.getCostPrice())) {
            newProd.setCostPrice(product.getCostPrice());
        }
        if (!oldProd.getSalePrice().equals(product.getSalePrice())) {
            newProd.setSalePrice(product.getSalePrice());
        }
        if (!oldProd.getVipPrice().equals(product.getVipPrice())) {
            newProd.setVipPrice(product.getVipPrice());
        }
        if (!oldProd.getWarnValue().equals(product.getWarnValue())) {
            newProd.setWarnValue(product.getWarnValue());
        }
        if (!oldProd.getFirstCid().equals(product.getFirstCid())) {
            newProd.setFirstCid(product.getFirstCid());
        }
        if (product.getSecondCid() != null) {
            if (oldProd.getSecondCid() == null || !oldProd.getSecondCid().equals(product.getSecondCid())) {
                newProd.setSecondCid(product.getSecondCid());
            }
        }
        if (product.getThirdCid() != null) {
            if (oldProd.getSecondCid() == null || !oldProd.getThirdCid().equals(product.getThirdCid())) {
                newProd.setThirdCid(product.getThirdCid());
            }
        }
        return productMapper.updateById(newProd) == 1;
    }

    @Override
    public PageBean<ProductDto> getProdPageList(ProdPageParams params) {
        PageHelper.startPage(params.getPage(), params.getSize());
        Page<ProductDto> page = productMapper.getProdPageList(params);
        List<ProductDto> result = page.getResult();
        if (result != null && result.size() > 0) {
            result.forEach(p -> {
                String buyerId = params.getBuyerId();
                p.setFirstCname(productCategoryService.getCatName(RedisKeyConstant.FIRST_CAT + buyerId, p.getFirstCid(), buyerId));
                if (StringUtils.isNotBlank(p.getSecondCid())) {
                    p.setSecondCname(productCategoryService.getCatName(RedisKeyConstant.SECOND_CAT + buyerId, p.getSecondCid(), buyerId));
                }
                if (StringUtils.isNotBlank(p.getThirdCid())) {
                    p.setThirdCname(productCategoryService.getCatName(RedisKeyConstant.THIRD_CAT + buyerId, p.getThirdCid(), buyerId));
                }
            });
        }
        return new PageBean<>(page.getPageNum(), page.getPageSize(), result, page.getTotal());
    }

    @Override
    public Integer getProdCountByCid(String cid) {
        QueryWrapper<Product> wrapper = new QueryWrapper<>();
        wrapper.eq("first_cid", cid).
                or().eq("second_cid", cid)
                .or().eq("third_cid", cid);
        return productMapper.selectCount(wrapper);
    }

    @Override
    public ProductDto getProdDtoByPid(String pid) {
        Product product = productMapper.selectById(pid);
        if (product == null) {
            return null;
        }
        ProductDto dto = new ProductDto();
        BeanUtils.copyProperties(product, dto);
        String buyerId = product.getBuyerId();
        dto.setFirstCname(productCategoryService.getCatName(RedisKeyConstant.FIRST_CAT + buyerId, dto.getFirstCid(), buyerId));
        if (StringUtils.isNotBlank(dto.getSecondCid())) {
            dto.setSecondCname(productCategoryService.getCatName(RedisKeyConstant.SECOND_CAT + buyerId, dto.getSecondCid(), buyerId));
        }
        if (StringUtils.isNotBlank(dto.getThirdCid())) {
            dto.setThirdCname(productCategoryService.getCatName(RedisKeyConstant.THIRD_CAT + buyerId, dto.getThirdCid(), buyerId));
        }
        return dto;
    }

    @Override
    public List<ProductDto> getProdDtoByPids(List<String> ids) {
        List<ProductDto> dtos = new ArrayList<>();
        QueryWrapper<Product> wrapper = new QueryWrapper<>();
        wrapper.in("pid", ids);
        List<Product> products = productMapper.selectList(wrapper);
        products.forEach(product -> {
            ProductDto dto = new ProductDto();
            BeanUtils.copyProperties(product, dto);
            String buyerId = product.getBuyerId();
            dto.setFirstCname(productCategoryService.getCatName(RedisKeyConstant.FIRST_CAT + buyerId, dto.getFirstCid(), buyerId));
            if (StringUtils.isNotBlank(dto.getSecondCid())) {
                dto.setSecondCname(productCategoryService.getCatName(RedisKeyConstant.SECOND_CAT + buyerId, dto.getSecondCid(), buyerId));
            }
            if (StringUtils.isNotBlank(dto.getThirdCid())) {
                dto.setThirdCname(productCategoryService.getCatName(RedisKeyConstant.THIRD_CAT + buyerId, dto.getThirdCid(), buyerId));
            }
            dtos.add(dto);
        });
        return dtos;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addStockingNumber(List<Product> products) {
        return productMapper.addStockingNumber(products);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer reduceStockingNumber(List<Product> products) {
        return productMapper.reduceStockingNumber(products);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateStockingNumber(List<Product> products) {
        return productMapper.updateStockingNumber(products);
    }

    @Override
    public List<ProductDto> getWarnProd(String buyerId) {
        List<ProductDto> result = productMapper.getWarnProd(buyerId);
        if (result != null && result.size() > 0) {
            result.forEach(p -> {
                p.setFirstCname(productCategoryService.getCatName(RedisKeyConstant.FIRST_CAT + buyerId, p.getFirstCid(), buyerId));
                if (StringUtils.isNotBlank(p.getSecondCid())) {
                    p.setSecondCname(productCategoryService.getCatName(RedisKeyConstant.SECOND_CAT + buyerId, p.getSecondCid(), buyerId));
                }
                if (StringUtils.isNotBlank(p.getThirdCid())) {
                    p.setThirdCname(productCategoryService.getCatName(RedisKeyConstant.THIRD_CAT + buyerId, p.getThirdCid(), buyerId));
                }
            });
        }
        return result;
    }
}
